package otcv.hr.controller;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import otcv.hr.Constants;
import otcv.hr.log.Logger;
import otcv.hr.util.Util;

/**
 * @author : H-Thien
 * @comment : Controller Sevlet
 */
public class Controller extends HttpServlet {

	protected HashMap events = new HashMap();

	/**
	 * @comment :
	 */
	@Override
	public void init() throws ServletException {
		ResourceBundle bundle = ResourceBundle.getBundle("Action");
		Enumeration e = bundle.getKeys();
		while (e.hasMoreElements()) {
			String key = (String) e.nextElement();
			String value = bundle.getString(key);

			try {
				ActionServlet event = (ActionServlet) Class.forName(value)
						.newInstance();
				events.put(key, event);

				Logger.info("Event:" + key + ", handler:"
						+ event.getClass().getName());
			} catch (Exception ex) {
				Logger.error("Event:" + key + ", No handler found! " + value);

			}
		}

		Enumeration servletParams = this.getInitParameterNames();
		while (servletParams.hasMoreElements()) {
			String aName = (String) servletParams.nextElement();
			String aValue = this.getInitParameter(aName);

			Logger.info("Servlet Parameter name:" + aName + ", value:" + aValue);
		}

		ServletContext sc = getServletContext();
		Enumeration webappParams = sc.getInitParameterNames();
		while (webappParams.hasMoreElements()) {
			String wName = (String) webappParams.nextElement();
			String wValue = sc.getInitParameter(wName);

			Logger.info("Webapp parameter name:" + wName + ", value:" + wValue);
		}
	}

	/**
	 * @comment :
	 */
	public void printParameter(HttpServletRequest req) {
		Enumeration param = req.getParameterNames();
		while (param.hasMoreElements()) {
			String pName = (String) param.nextElement();
			String pValue = req.getParameter(pName);

			Logger.info("Param Name:" + pName + "-->Value:" + pValue);
		}
	}

	/**
	 * @comment :
	 */
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		doPost(req, res);
	}

	/**
	 * @comment :
	 */
	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		Logger.info("[doPost]new request");
		String targetURL = "";

		req.setCharacterEncoding("utf-8");
		String event = validateEvent(req);
		ActionServlet handler = getEventHandler(event);

		try {
			// Session check
			if (!isSession(event, req, targetURL)) {
				handler = getEventHandler(Constants.SESSION_OUT_ACTION);
			}

			// jsp file check
			String realFile = req.getSession().getServletContext()
					.getRealPath(targetURL);
			File f = new File(realFile);
			if (!f.exists()) {
				req.setAttribute("error", realFile + " do not exist.");
				handler = getEventHandler(Constants.ERROR_ACTION);
			}

			handler.process(getServletContext(), req, res);

		} catch (MissingResourceException mre) {
			req.setAttribute("error", mre.toString());
			handler = getEventHandler(Constants.ERROR_ACTION);
			try {
				handler.process(getServletContext(), req, res);
			} catch (Exception xe) {
			}
		} catch (Exception e) {
			System.out.println("Controll error = " + e.toString());

			req.setAttribute("error", e.toString());
			handler = getEventHandler(Constants.ERROR_ACTION);
			try {
				handler.process(getServletContext(), req, res);
			} catch (Exception xe) {
			}
		} finally {
			handler.forward(req, res);
		}
	}

	/**
	 * @comment : Session check
	 */
	protected boolean isSession(String event, HttpServletRequest req,
			String targetURL) {
		boolean isSession = true;
		boolean sessionYn = true;

		HttpSession session = req.getSession();

		String liveYn = (String) session.getAttribute("ses_check");
		if (Util.isNotNull(liveYn)) {
			sessionYn = false;
		}

		if (sessionYn) {
			// session not check
			if (event != null && !event.equals(Constants.ERROR_ACTION)
					&& !event.equals(Constants.UNKNOWN_ACTION)
					&& !event.equals(Constants.SESSION_OUT_ACTION)
					&& !event.equals(Constants.LOGIN_FORM_ACTION)
					&& !event.equals(Constants.LOGIN_PROC_ACTION)
					&& !event.equals(Constants.LOGOUT_ACTION)) {
				isSession = false;
			}
		}

		return isSession;
	}

	/**
	 * @comment : Check that the call to action is valid.
	 */
	protected String validateEvent(HttpServletRequest req) {
		String e = req.getParameter(Constants.ACTION);
		if (e == null || !events.containsKey(e)) {
			e = Constants.UNKNOWN_ACTION;
		}
		Logger.info("validate event = " + e);
		return e;
	}

	/**
	 * @comment : Action.properties file to find the actual action class.
	 */
	protected ActionServlet getEventHandler(String e) {
		ActionServlet h;
		try {
			h = (ActionServlet) events.get(e);
		} catch (Exception exc) {
			h = (ActionServlet) events.get(Constants.UNKNOWN_ACTION);
		}

		Logger.info("[getEventHandler] handler=" + h.getClass().getName());
		return h;
	}
}